/*
 *@(#)HomeController.java 1.0 Feb 1, 2008
 *Copyright Fution Bai
 *
 */
package codebush.web.controller;

import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.servlet.ModelAndView;

import codebush.domain.Article;
import codebush.domain.Comment;
import codebush.domain.Users;
import codebush.service.Get;
import codebush.service.Home;
import codebush.service.Subject;
import codebush.service.Tag;
import codebush.util.HttpUtil;
import codebush.util.ImageCompressionScaleImage;
import codebush.web.WebHelp;

/**
 * 
 * @author Fution Bai
 * @since 1.0
 */
@Controller
public class HomeController {

	public static final String defaultTag = "general";
	
	private final Home home;
	private final Subject subject;
	private final Tag tag;
	private final Get get;

	@Autowired
	public HomeController(Home home, Subject subject, Tag tag, Get get) {
		this.home = home;
		this.subject = subject;
		this.tag = tag;
		this.get = get;
	}

	public Home getHome() {
		return home;
	}

	public Subject getSubject() {
		return subject;
	}

	public Tag getTag() {
		return tag;
	}

	public Get getGet() {
		return get;
	}

	/**
	 * index request for home servlet
	 * 
	 * @return
	 */
	@RequestMapping("/")
	public ModelAndView index(HttpSession session) {
		ModelAndView mav = new ModelAndView();
		Map<String, Object> model = new HashMap<String, Object>();
		int userId = HttpUtil.getUserId(session);
		List<Article> list = (List<Article>) this.getGet().top("article", "post_time", userId);
		List<Comment> latestComments = (List<Comment>) this.getGet().getLatestCommentsByUserId(userId);
		model.put("featuredArticles", list);
		model.put("latestComments", latestComments);
		mav.setViewName("/index");
		mav.addAllObjects(model);
		return mav;
	}

	/**
	 * post a new article
	 * 
	 * @param title
	 * @param content
	 * @param tag
	 * @return
	 */
	@RequestMapping("/post")
	public ModelAndView postArticle(@RequestParam(value = "title", required = false)
	String title, @RequestParam(value = "content", required = false)
	String content, @RequestParam(value = "tag", required = false)
	String tag, @RequestParam(value = "type", required = false)
	String type, HttpSession session) {
		ModelAndView mav = new ModelAndView();
		if (session.getAttribute("email") == null) {
			mav.addObject("warnMessage", "你只有登录了以后才可以发表文章哦");
			mav.addObject("redirectUrl", "/home/article/post");
			mav.setViewName("/support/signin");
			return mav;
		}
		if (title == null || title.equals("") || content == null || content.equals("")) {
			mav.setViewName("/article_post");
			return mav;
		}

		if (tag == null || tag.equals("")) {
			tag = defaultTag;
		}
		this.getTag().doTag(tag);
		
		int userId = HttpUtil.getUserId(session);
		this.getHome().postArticle(title, content, tag, Integer.parseInt(type), userId);
		mav.setViewName("redirect:/home/?");
		return mav;
	}

	/**
	 * modify an existed article, only can do by the owner
	 * 
	 * @param title
	 * @param content
	 * @param tag
	 * @param type
	 * @param session
	 * @return
	 */
	@RequestMapping("/modify")
	public ModelAndView modifyArticle(@RequestParam(value = "aid")
	String articleId, @RequestParam(value = "articleOwnerId", required = false)
	String articleOwnerId, @RequestParam(value = "title", required = false)
	String title, @RequestParam(value = "content", required = false)
	String content, @RequestParam(value = "tag", required = false)
	String tag, @RequestParam(value = "type", required = false)
	String type, HttpSession session) {
		ModelAndView mav = new ModelAndView();
		if (articleOwnerId == null || title == null || content == null || type == null) {
			Article article = this.getGet().getArticle(Long.parseLong(articleId));
			mav.addObject(article);
			mav.setViewName("/article_post");
			return mav;
		}
		if (HttpUtil.getUserId(session) != Integer.parseInt(articleOwnerId)) {
			mav.setViewName("/support/redirect/not_authorized");
			return mav;
		}
		if (tag != null && !tag.equals("")) {
			this.getTag().doTag(tag);
		}
		this.getHome().modifyArticle(Long.parseLong(articleId), title, content, tag, Integer.parseInt(type));
		mav.setViewName("redirect:/subject/thread?aid=" + articleId);
		return mav;
	}

	/**
	 * show a user's profile. The uid is required.
	 * 
	 * @param userId
	 * @return
	 */
	@RequestMapping("/profile")
	public ModelAndView profile(@RequestParam(value = "uid")
	int userId, @RequestParam(value = "offset", required = false)
	String off) {
		int offset = 0;
		if (off != null && !off.equals("")) {
			offset = Integer.parseInt(off);
		}
		List<Article> articles = this.getGet().getArticlesByUserId(userId, offset);
		int totalNum = this.getGet().getTotalNumOfArticlesByUserId(userId);
		Users user = this.getGet().getUser(userId);
		ModelAndView mav = new ModelAndView();
		Map<String, Object> model = new HashMap<String, Object>();
		model.put("articles", articles);
		model.put("totalNum", totalNum);
		model.put("offset", offset);
		model.put("user", user);
		mav.addAllObjects(model);
		mav.setViewName("/profile");
		return mav;
	}

	/**
	 * mail a subject to your friend
	 * 
	 * @param from
	 * @param to
	 * @param subject
	 * @param aid
	 * @return
	 */
	@RequestMapping("/email")
	public ModelAndView emailSubject(@RequestParam(value = "from", required = false)
	String from, @RequestParam(value = "to", required = false)
	String to, @RequestParam(value = "subject", required = false)
	String subject, @RequestParam(value = "aid", required = false)
	String aid, @RequestParam(value = "recContent", required = false)
	String recContent) {
		ModelAndView mav = new ModelAndView();
		if (from != null && !from.equals("")) {
			mav.addObject("from", from);
		}
		if (to != null && !to.equals("")) {
			mav.addObject("to", to);
		}
		if (subject != null && !subject.equals("")) {
			mav.addObject("subject", subject);
		}
		if (aid != null && !aid.equals("")) {
			mav.addObject("aid", aid);
		}
		if (from == null || from.equals("") || to == null || to.equals("") || subject == null || subject.equals("") || aid == null || aid.equals("")) {
			mav.setViewName("/email");
			return mav;
		}

		this.getSubject().emailSubject(from, to, subject, aid, recContent);
		mav.setViewName("redirect:/article/thread");
		return mav;
	}

	/**
	 * get some top subjects
	 * 
	 */
	public ModelAndView top() {
		ModelAndView mav = new ModelAndView();
		return mav;
	}

	/**
	 * uses to upload the user's picture. store the original one and the
	 * compressed one
	 * 
	 * @throws IOException
	 */
	@RequestMapping("/upload/myPicture")
	public ModelAndView uploadMyPicture(@RequestParam(value = "image", required = false)
	MultipartFile image, HttpSession session) throws IOException {
		ModelAndView mav = new ModelAndView();
		if (image == null) {
			mav.setViewName("/support/upload_mypicture");
			return mav;
		}
		if (image.getSize() > 5242880) {
			mav.addObject("warnMessage", "exceed the limit size 5M");
			mav.setViewName("/support/upload_mypicture");
			return mav;
		}
		int userId = HttpUtil.getUserId(session);

		this.getHome().storeMyPicture(userId, image.getInputStream(), (int) image.getSize());

		InputStream compressedInputStream = new ImageCompressionScaleImage().getInputStreamFromCompressedSavedFileImage(image.getInputStream(), 48, 48);
		this.getHome().storeCompressedMyPicture(userId, compressedInputStream, compressedInputStream.available());

		mav.setViewName("redirect:/home/?");
		return mav;
	}

	@RequestMapping("/delete")
	public ModelAndView deleteArticle(@RequestParam(value = "aid")
	String articleId, HttpSession session) {
		ModelAndView mav = new ModelAndView();
		this.getHome().deleteArticle(Long.parseLong(articleId));
		mav.setViewName("redirect:/home/?");
		return mav;
	}

	@RequestMapping("/admin")
	public ModelAndView admin(HttpSession session) {
		ModelAndView mav = new ModelAndView();
		mav.setViewName("admin");
		return mav;
	}

	@RequestMapping("/admin/deleteAccount")
	public ModelAndView deleteAccount(HttpSession session, HttpServletRequest request, HttpServletResponse response, @RequestParam(value = "_continue", required = false)
			String _continue) throws IOException {
		if (session.getAttribute("passwordVerified") == null) {
			WebHelp.sendRedirectToVerifyPassword(session, request, response);
			return null;
		}
		ModelAndView mav = new ModelAndView();
		if((Boolean)session.getAttribute("passwordVerified")){
			int userId = Integer.parseInt(session.getAttribute("userId").toString());
			this.getHome().deleteAccount(userId);
			WebHelp.invalidateUser(session, request, response);
		}
		mav.setViewName("redirect:/?");
		return mav;
	}
}
